from abc import ABC, abstractmethod  
import requests
import urllib.parse
from rest_framework.response import Response
from user.models import ThirdPartyAuth, UserModel
from user.ser import SfUserSerializer, ThirdPartyAuthSerializer
from tools.myjwt import mjwt
import requests, time
from urllib.parse import quote

class Product(ABC):  
    @abstractmethod  
    def geturl(self):  
        pass
    @abstractmethod
    def callback(self):
        pass
  
# 具体产品类
class Dingding(Product):  
   def __init__(self):
       self.client_id = "dingstqta9m1sphood0c"
       self.clientSecret= "-ryMdeXTuDUKvzRoTLiAgT1zdyIuFLr_OpIikkAP5rXur_lO70a1TaZGFEbz_rl4"
 
   def geturl(self):  
        redirect_uri = quote("http://127.0.0.1:8080/dingtalkcallback/")
        client_id = self.client_id
        url = "https://login.dingtalk.com/oauth2/auth?redirect_uri=%s&response_type=code&client_id=%s&scope=openid&state=dddd&prompt=consent"%(redirect_uri, client_id)
        # https://login.dingtalk.com/oauth2/auth?redirect_uri=http://127.0.0.1:8080/#/ding_talk_callback/&response_type=code&client_id=dingstqta9m1sphood0c&scope=openid&state=dddd&prompt=consent
        print(url)
        return url

   def callback(self, **kwargs):
        authCode = kwargs.get('authCode')
        print("回调的authCode：" , authCode)

        data = {
            "clientId": self.client_id,
            "clientSecret": self.clientSecret,
            "code": authCode,
            "grantType": "authorization_code"
        }
        resp = requests.post('https://api.dingtalk.com/v1.0/oauth2/userAccessToken', json=data).json()
        accessToken = resp.get('accessToken')

        headers = {"x-acs-dingtalk-access-token": accessToken}
        resp = requests.get('https://api.dingtalk.com/v1.0/contact/users/me', headers=headers).json()
        
        name = resp.get('nick')
        uid = resp.get('openId')
        phone = resp.get('mobile')

        # 登录，写入三方登录表和用户表
        sfl = ThirdPartyAuth.objects.filter(uid=uid, type=1).first()
        if not sfl:
            # 写入用户表
            # 手机号用户存在直接绑定,不存在注册新用户
            user = UserModel.objects.filter(phone=phone).first()
            if not user:
                userinfo = {
                    "name": name,
                    "phone": phone,
                    "password": phone,
                    "username": phone
                }
                us = SfUserSerializer(data=userinfo)
                print("写入用户表", us)
                if us.is_valid():
                    user = us.save()
                else:
                    return Response({"code": 10001, "msg": us.errors})
            # 写入三方登录表
            sfinfo = {
                "type": 1,
                "token": accessToken,
                "uid": uid,
                "user": user.id
            }
            print("写入三方登录表", sfinfo)
            sfs = ThirdPartyAuthSerializer(data=sfinfo)

            if sfs.is_valid():
                sfs.save()
            else:
                return Response({"code": 10001, "msg": sfs.errors})
        else:
            user = sfl.user
            sfl.token = accessToken
            sfl.save()

        # 生成jwt token并返回前端
        print("user:", user)
        payload = {"userid": user.id, "username": user.username, "exp": int(time.time()) + 60 * 60 * 2}
        token = mjwt.jwt_encode(payload)
        payload["exp"] = int(time.time() + 60 * 60 * 24 * 2)
        refreshToken = mjwt.jwt_encode(payload)
        query = [f"userid={payload['userid']}", f"username={payload['username']}", f"token={token}",
                 f"refreshToken={refreshToken}"]
        return Response({"code":200,"token":token})
      
 #创建工厂类
class ProductFactory:  
    def create_product(self, product_type):  
        if product_type == "dingding":  
            return Dingding()
        else:  
            raise ValueError("无效的产品类型")  

factory = ProductFactory()

